home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
kcl.lha
/
c
/
fasl_reloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-04
|
10KB
|
506 lines
/*
(C) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
*/
/*
fasl_reloc.c
DG-SPECIFIC
fasl relocation routines
*/
#include <stdio.h>
#include "../h/fasl.h"
#include "../h/fasl_global.h"
#include "../h/fasl_reloc.h"
int fas_base; /* base */
int fas_dword; /* data word */
int fas_pc; /* program counter */
int fas_result; /* result */
bit_relocation(reloc, bit_p, dword_p)
short reloc; /* extended relocation */
FAS_BIT_P bit_p; /* bit dictionary pointer */
short *dword_p; /* dictionaried word pointer */
{
}
relocation(reloc, base_p, dword_p)
short reloc; /* extended relocation */
short *base_p; /* base pointer */
short *dword_p; /* dictionaried word pointer */
{
short base_no; /* base no */
if (reloc < RL_ADDR_WORD_32_31)
FEerror("Illegal relocation.", 0);
base_no = *base_p; /* get base */
if (fas_relocation_by_table == TRUE) {
part_table_p = fasl_get_table(base_no);
fas_base = part_table_p->part_addr;
} else
fas_base = fasl_get_addr(base_no);
if (reloc > RL_DATA_SUB2_32_32)
fas_dword = *dword_p; /* 16 bits data word */
else
fas_dword = *((int *)dword_p); /* 32 bits data word */
fas_pc = dword_p;
switch(reloc) {
case RL_ADDR_WORD_32_31: addr_word_32_31();
break;
case RL_ADDR_BYTE_32_31: addr_byte_32_31();
break;
case RL_ADDR_PC_REL_32_31: addr_pc_rel_32_31();
break;
case RL_ADDR_PC_BYTE_32_31: addr_pc_byte_32_31();
break;
case RL_ADDR_WORD_32_28: addr_word_32_28();
break;
case RL_ADDR_BYTE_32_28: addr_byte_32_28();
break;
case RL_ADDR_PC_REL_32_28: addr_pc_rel_32_28();
break;
case RL_ADDR_PC_BYTE_32_28: addr_pc_byte_32_28();
break;
case RL_ADDR_WORD_28_31: addr_word_28_31();
break;
case RL_ADDR_BYTE_28_31: addr_byte_28_31();
break;
case RL_ADDR_PC_REL_28_31: addr_pc_rel_28_31();
break;
case RL_ADDR_PC_BYTE_28_31: addr_pc_byte_28_31();
break;
case RL_DATA_ADD_32_32: data_add_32_32();
break;
case RL_DATA_SUB1_32_32: data_sub1_32_32();
break;
case RL_DATA_MUL_32_32: data_mul_32_32();
break;
case RL_DATA_SUB2_32_32: data_sub2_32_32();
break;
case RL_DATA_ADD_32_16S: data_add_32_16s();
break;
case RL_DATA_SUB1_32_16S: data_sub1_32_16s();
break;
case RL_DATA_MUL_32_16S: data_mul_32_16s();
break;
case RL_DATA_SUB2_32_16S: data_sub2_32_16s();
break;
case RL_DATA_ADD_32_16U: data_add_32_16u();
break;
case RL_DATA_SUB1_32_16U: data_sub1_32_16u();
break;
case RL_DATA_MUL_32_16U: data_mul_32_16u();
break;
case RL_DATA_SUB2_32_16U: data_sub2_32_16u();
break;
case RL_DATA_ADD_32_16: data_add_32_16();
break;
case RL_DATA_SUB1_32_16: data_sub1_32_16();
break;
case RL_DATA_MUL_32_16: data_mul_32_16();
break;
case RL_DATA_SUB2_32_16: data_sub2_32_16();
break;
case RL_ADDR_WORD_32_15U: addr_word_32_15u();
break;
case RL_ADDR_BYTE_32_15U: addr_byte_32_15u();
break;
case RL_ADDR_PC_REL_32_15U: addr_pc_rel_32_15u();
break;
case RL_ADDR_PC_BYTE_32_15U: addr_pc_byte_32_15u();
break;
case RL_ADDR_WORD_32_15S: addr_word_32_15s();
break;
case RL_ADDR_BYTE_32_15S: addr_byte_32_15s();
break;
case RL_ADDR_PC_REL_32_15S: addr_pc_rel_32_15s();
break;
case RL_ADDR_PC_BYTE_32_15S: addr_pc_byte_32_15s();
break;
default: unexpect_reloc(reloc);
break;
} /* end of switch */
if (reloc > RL_DATA_SUB2_32_32)
*dword_p = fas_result & LOW16_BITS; /* 16 bits */
else
*((int *)dword_p) = fas_result; /* 32 bits */
}
addr_word_32_31()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT;
fas_dword &= LOW31_BITS;
fas_result = fas_base + fas_dword;
fas_result = indirect | (fas_result & LOW31_BITS);
}
addr_byte_32_31()
{
fas_result = fas_base * 2 + fas_dword;
}
addr_pc_rel_32_31()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT;
fas_dword &= LOW31_BITS;
fas_pc &= LOW28_BITS;
fas_result = fas_base + fas_dword;
fas_result = (fas_result - fas_pc) | indirect;
}
addr_pc_byte_32_31()
{
fas_result = fas_base * 2 + fas_dword;
fas_result -= (fas_pc & LOW28_BITS);
}
addr_word_32_28()
{
int ring;
ring = fas_dword & RING_BITS;
fas_result = fas_base + (fas_dword & LOW28_BITS);
if ((fas_result < 0) |
(fas_result >= 02000000000))
rloverflow();
fas_result |= ring;
}
addr_byte_32_28()
{
int ring;
ring = fas_dword & RING_BITS;
fas_result = fas_base + 2 * (fas_dword & LOW28_BITS);
if ((fas_result < 0) |
(fas_result >= 04000000000))
rloverflow();
fas_result |= (2 * ring);
}
addr_pc_rel_32_28()
{
int indirect;
fas_pc &= LOW28_BITS;
indirect = fas_dword & INDIRECT_BIT;
fas_result = fas_base + (fas_dword & LOW28_BITS);
if ((fas_result < 0) |
(fas_result >= 2000000000))
rloverflow();
fas_result = ((fas_result - fas_pc) & LOW31_BITS) | indirect;
}
addr_pc_byte_32_28()
{
fas_result = fas_base + 2 * (fas_dword | LOW28_BITS);
if ((fas_result < 0) |
(fas_result >= 04000000000))
rloverflow();
fas_result -= 2 * fas_pc;
}
addr_word_28_31()
{
int ring, indirect;
ring = fas_base & RING_BITS;
fas_base &= LOW28_BITS;
indirect = fas_dword & INDIRECT_BIT;
fas_dword &= LOW31_BITS;
fas_result = fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 02000000000))
rloverflow();
fas_result = indirect | ring | fas_result;
}
addr_byte_28_31()
{
int ring;
ring = fas_base & RING_BITS;
fas_base &= LOW28_BITS;
fas_result = 2 * fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 04000000000))
rloverflow();
fas_result |= ring * 2;
}
addr_pc_rel_28_31()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT;
fas_base &= LOW28_BITS;
fas_dword &= LOW31_BITS;
fas_pc &= LOW28_BITS;
fas_result = fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 02000000000))
rloverflow();
fas_result = ((fas_result - fas_pc) & LOW31_BITS) | indirect;
}
addr_pc_byte_28_31()
{
fas_base &= LOW28_BITS;
fas_pc &= LOW28_BITS;
fas_result = 2 * fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 04000000000))
rloverflow();
fas_result -= 2 * fas_pc;
}
data_add_32_32()
{
fas_result = fas_base + fas_dword;
}
data_sub1_32_32()
{
fas_result = fas_base - fas_dword;
}
data_mul_32_32()
{
fas_result = fas_base * fas_dword;
}
data_sub2_32_32()
{
fas_result = fas_dword - fas_base;
}
data_add_32_16s()
{
fas_result = fas_base + fas_dword;
if ((fas_result < -0100000) |
(fas_result >= 0100000))
rloverflow();
}
data_sub1_32_16s()
{
fas_result = fas_base - fas_dword;
if ((fas_result < -100000) |
(fas_result >= 0100000))
rloverflow();
}
data_mul_32_16s()
{
fas_result = fas_base * fas_dword;
if ((fas_result < -0100000) |
(fas_result >= 0100000))
rloverflow();
}
data_sub2_32_16s()
{
fas_result = fas_dword - fas_base;
if ((fas_result < -0100000) |
(fas_result >= 0100000))
rloverflow();
}
data_add_32_16u()
{
data_16u();
fas_result = fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
}
data_sub1_32_16u()
{
data_16u();
fas_result = fas_base - fas_dword;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
}
data_mul_32_16u()
{
data_16u();
fas_result = fas_base * fas_dword;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
}
data_sub2_32_16u()
{
data_16u();
fas_result = fas_dword - fas_base;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
}
data_add_32_16()
{
data_16u();
fas_result = fas_base + fas_dword;
}
data_sub1_32_16()
{
data_16u();
fas_result = fas_base - fas_dword;
}
data_mul_32_16()
{
data_16u();
fas_result = fas_base * fas_dword;
}
data_sub2_32_16()
{
data_16u();
fas_result = fas_dword - fas_base;
}
addr_word_32_15u()
{
int high_4bits;
high_4bits = fas_dword & HIGH4_BITS16;
data_15u(); /* 15 bits unsigned */
fas_dword &= LOW15_BITS;
fas_base &= LOW28_BITS;
fas_result = fas_base + fas_dword;
if ((fas_result < 0) ||
(fas_result >= 0100000))
rloverflow();
fas_result = (high_4bits | fas_result) & LOW16_BITS;
}
addr_byte_32_15u()
{
fas_base &= LOW28_BITS;
fas_result = 2 * fas_base + fas_dword;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
fas_result &= LOW8_BITS;
}
addr_pc_rel_32_15u()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT16;
data_15u();
fas_base &= LOW28_BITS;
fas_pc &= LOW28_BITS;
fas_result = fas_base - fas_pc + fas_dword;
if ((fas_result < 0) |
(fas_result >= 0100000))
rloverflow();
fas_result |= indirect;
}
addr_pc_byte_32_15u()
{
fas_base &= LOW28_BITS;
fas_pc &= LOW28_BITS;
fas_result = 2 * fas_base + 2 * fas_pc + fas_dword;
if ((fas_result < 0) |
(fas_result >= 0200000))
rloverflow();
fas_result &= LOW8_BITS;
}
addr_word_32_15s()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT16;
data_15s();
fas_base &= LOW28_BITS;
fas_result = fas_base + fas_dword;
if ((fas_result < -040000) |
(fas_result >= 040000))
rloverflow();
fas_result = (fas_result & LOW15_BITS) | indirect;
}
addr_byte_32_15s()
{
fas_base &= LOW28_BITS;
fas_result = 2 * fas_base + fas_dword;
if ((fas_result < -0100000) |
(fas_result >= 0100000))
rloverflow();
}
addr_pc_rel_32_15s()
{
int indirect;
indirect = fas_dword & INDIRECT_BIT16;
data_15s();
fas_base &= LOW28_BITS;
fas_pc &= LOW28_BITS;
fas_result = fas_base + fas_pc - fas_dword;
if ((fas_result < -040000) |
(fas_result >= 040000))
rloverflow();
fas_result = (fas_result & LOW15_BITS) | indirect;
}
addr_pc_byte_32_15s()
{
fas_base &= LOW28_BITS;
fas_pc &= LOW28_BITS;
fas_result = 2 * fas_base - 2 * fas_pc + fas_dword;
if ((fas_result < -010000) |
(fas_result >= 010000))
rloverflow();
fas_result &= LOW8_BITS;
}
data_15u()
{
fas_dword &= LOW15_BITS;
}
data_15s()
{
if ((fas_dword & BIT_17) != 0)
fas_dword |= ( ~LOW15_BITS);
else
fas_dword &= LOW15_BITS;
}
data_16u()
{
fas_dword &= LOW16_BITS;
}
rloverflow()
{
FEerror("Relocation overflow.", 0);
}
unexpect_reloc(reloc)
short reloc;
{
FEerror("Unexpected relocation.", 0);
}